#include <jni.h>
#include <unistd.h>
#include <android/log.h>
#include <fmod.hpp>


#define LOGI(FORMATTER, ...) __android_log_print(ANDROID_LOG_INFO,"cherry_ndk",FORMATTER,__VA_ARGS__)
#define LOGE(FORMATTER, ...) __android_log_print(ANDROID_LOG_ERROR,"cherry_ndk",FORMATTER,__VA_ARGS__)

#define MODE_NORMAL 0
#define MODE_LUOLI 1
#define MODE_DASHU 2
#define MODE_JINGSONG 3
#define MODE_GAOGUAI 4
#define MODE_KONGLING 5

using namespace FMOD;

extern "C" JNIEXPORT void JNICALL
Java_com_cherry_ndkdemo_FmodUtils_fix(JNIEnv *env, jclass clazz, jstring jpath, jint jtype) {
    const char *path = env->GetStringUTFChars(jpath, nullptr);

    System *system;
    Sound *sound;
    Channel *channel;
    DSP *dsp;
    float frequency;
    bool playing = true;
    FMOD_RESULT result;

    result = System_Create(&system);
    if (result != FMOD_OK) {
        LOGE("%s", "System_Create failure");
        return;
    }
    //手机录音一般是16位  如果是32位的音频要填32 否则无法播放声音
    result = system->init(16, FMOD_INIT_NORMAL, nullptr);
    if (result != FMOD_OK) {
        LOGE("%s", "init failure");
        return;
    }
    //创建声音
    result = system->createSound(path, FMOD_DEFAULT, 0, &sound);
    if (result != FMOD_OK) {
        LOGE("%s", "createSound failure");
        return;
    }
    switch (jtype) {
        case MODE_NORMAL:
            result = system->playSound(sound, 0, false, &channel);
            if (result != FMOD_OK) {
                LOGE("%s", "MODE_NORMAL 播放失败");
            }
            break;
        case MODE_LUOLI:
            system->createDSPByType(FMOD_DSP_TYPE_PITCHSHIFT, &dsp);
            dsp->setParameterFloat(FMOD_DSP_PITCHSHIFT_PITCH, 2.5);
            result = system->playSound(sound, 0, false, &channel);
            channel->addDSP(0, dsp);
            if (result != FMOD_OK) {
                LOGE("%s", "MODE_LUOLI 播放失败");
            }
            break;
        case MODE_DASHU:
            system->createDSPByType(FMOD_DSP_TYPE_PITCHSHIFT, &dsp);
            dsp->setParameterFloat(FMOD_DSP_PITCHSHIFT_PITCH, 0.8);
            result = system->playSound(sound, 0, false, &channel);
            channel->addDSP(0, dsp);
            if (result != FMOD_OK) {
                LOGE("%s", "MODE_DASHU 播放失败");
            }
            break;
        case MODE_JINGSONG:
            system->createDSPByType(FMOD_DSP_TYPE_TREMOLO, &dsp);
            dsp->setParameterFloat(FMOD_DSP_TREMOLO_SKEW, 0.5);
            result = system->playSound(sound, 0, false, &channel);
            channel->addDSP(0, dsp);
            if (result != FMOD_OK) {
                LOGE("%s", "MODE_JINGSONG 播放失败");
            }
            break;
        case MODE_GAOGUAI:
            result = system->playSound(sound, 0, false, &channel);
            //提高说话的速度
            channel->getFrequency(&frequency);
            frequency = frequency * 1.6;
            channel->setFrequency(frequency);
            if (result != FMOD_OK) {
                LOGE("%s", "MODE_GAOGUAI 播放失败");
            }
            break;
        case MODE_KONGLING:
            system->createDSPByType(FMOD_DSP_TYPE_ECHO, &dsp);
            dsp->setParameterFloat(FMOD_DSP_ECHO_DELAY, 300);
            dsp->setParameterFloat(FMOD_DSP_ECHO_FEEDBACK, 20);
            result = system->playSound(sound, 0, false, &channel);
            channel->addDSP(0, dsp);
            if (result != FMOD_OK) {
                LOGE("%s", "MODE_KONGLING 播放失败");
            }
            break;
    }
    system->update();
    //进程休眠 单位微秒 us
    //每秒钟判断是否在播放
    while (playing) {
        channel->isPlaying(&playing);
        usleep(1000 * 1000);
    }
    goto END;
    //释放资源
    END:
    env->ReleaseStringUTFChars(jpath, path);
    sound->release();
    system->close();
    system->release();
}

